; *******************************************************************
; * exp3_2.asm
; * LLP STUDIO Chen Zhepeng
; * V1.1
; * 2023-11-17 (Updated)
; * 共阳数码管同时显示0 ~ F，从0开始，每隔0.5 s数字加1，
; * 至F后从0重新开始
; *******************************************************************
; * V1.1, 2023-11-17: 关闭了LED点阵的显示
; * V1.0, 2023-09-18: Initial version.
; *******************************************************************

P4  DATA    0C0H
P6  DATA    0E8H
P4M1 DATA   0b3H
P4M0 DATA   0b4H
P6M1 DATA   0CBH
P6M0 DATA   0CCH
HC595_SI  BIT P4.4  ; 74HC595串行输入端
HC595_SCK BIT P4.2  ; 74HC595移位时钟输入
HC595_RCK BIT P4.3  ; 74HC595锁存时钟输入

ORG 0000H
LJMP Main
ORG 0100H
Main:
; P4口P4.1推挽，其他准双向
MOV P4M1, #00H
MOV P4M0, #01H
; 设置P6口为推挽输出
MOV P6M1, #00H
MOV P6M0, #0FFH
MOV R1, #0  ; 段码计数器，初始为0
SETB P4.0  ; 关闭LED
MainLoop:
LCALL Disp
LCALL DELAY500MS
LJMP MainLoop

SegTable:
DB 0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8
DB 0X80, 0X90, 0X88, 0X83, 0XC6, 0XA1, 0X86, 0X8E

; * @brief       向74HC595D发送一个字节
; * @param       ACC: 要发送的字节数据（存放在累加器中）
; * @retval      无
Hc595SendByte:
PUSH 02H
MOV R2, #8
Hc595SendLoop:
RLC A
MOV HC595_SI, C
SETB HC595_SCK
CLR HC595_SCK
DJNZ R2, Hc595SendLoop
POP 02H
RET

; * @brief       数码管动态显示
; * @param       无
; * @retval      无
Disp:
MOV A, #00H
LCALL Hc595SendByte  ; 关闭点阵
MOV A, #0FFH
LCALL Hc595SendByte  ; 点亮所有数码管
NOP
SETB HC595_RCK  ; 上升沿并行锁存到输出端
NOP
CLR HC595_RCK  ; 锁存输出数据
MOV DPTR, #SegTable
MOV A, R1
MOVC A, @A + DPTR
MOV P6, A  ; 输出段码
CJNE R1, #15, Increase
MOV R1, #0
JMP Renew
Increase:
INC R1
Renew:
RET

; * @brief       0.5 s延时（由STC-ISP生成）
; * @param       无
; * @retval      无
DELAY500MS:			;@24.000MHz
	NOP
	NOP
	PUSH	30H
	PUSH	31H
	PUSH	32H
	MOV		30H,#61
	MOV		31H,#225
	MOV		32H,#60
NEXT:
	DJNZ	32H,NEXT
	DJNZ	31H,NEXT
	DJNZ	30H,NEXT
	POP		32H
	POP		31H
	POP		30H
	RET

END
